package cn.yuanqiao.archive.shuzihua.utils;

import cn.yuanqiao.archive.appManager.domain.*;
import cn.yuanqiao.archive.appManager.mapper.*;
import cn.yuanqiao.archive.appManager.service.ITenantSysDictTypeService;
import cn.yuanqiao.archive.wenjianzhengli.utils.UploadDataListener;
import cn.yuanqiao.common.core.domain.entity.SysDept;
import cn.yuanqiao.common.core.domain.entity.SysUser;
import cn.yuanqiao.common.utils.SnowflakeIdGenerator;
import cn.yuanqiao.common.utils.StringUtils;
import cn.yuanqiao.common.core.domain.model.LoginUser;
import cn.yuanqiao.feignService.ApiSystemService;
import cn.yuanqiao.feignService.RemoteSysDeptService;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.SqlSessionTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @ProjectName: cn.yuanqiao.archive.shuzihua.utils
 * @ClassName: CatalogueUploadDao
 * @Author: lenovo
 * @Description: hbWang
 * @Date: 2024/1/16 14:34
 * @Version: 1.0
 **/
@Component
public class CatalogueUploadDao {
    protected final Logger logger = LoggerFactory.getLogger(this.getClass());
    private SqlSessionTemplate sqlSessionTemplate;

    /**
     * 0 = 只解析表头  1 = 解析数据
     */
    private Integer type;

    /**
     * 错误信息
     */
    private StringBuilder msg = new StringBuilder();

    /**
     * 表头
     */
    private List<Map<String, String>> headMap;

    /**
     * 门类
     */
    private TenantCategory category;

    /**
     * 导入耗时
     */
    private Long time;

    /**
     * 当前用户
     */
    private LoginUser loginUser;

    /**
     * 创建时间
     */
    private String createTime;

    /**
     * 数据处理
     */
    private JSONObject data;

    /**
     * 数据处理
     */
    private List<Map<String, String>> failData = new ArrayList<>();

    /**
     * 字典
     */
    private ITenantSysDictTypeService sysDictTypeService;

    /**
     * 元数据明细中有默认值的
     */
    private List<TenantMdataList> mdataList;

    /**
     * 记录分片处理次数
     */
    private Integer num = 0;

    /**
     * 总计导入条数
     */
    private Integer zongshu = 0;

    /**
     * 成功条数
     */
    private Integer successSun = 0;

    /**
     * 失败条数
     */
    private Integer errorSun = 0;

    /**
     * 处理完成的数据
     */
    private List<Map<String, String>> saveData = new ArrayList<>();

    private ApiSystemService userService;

    private RemoteSysDeptService deptService;

    private ArchiveMapper archiveMapper;

    public void save(List<Map<Integer, String>> list) {
        //data = {"categoryId":"195757160578289664","state":"1","jsType":"1","type":"3","colNames":
        // [{"xlsNum":"0","xlsName":"项目名称","name":"XMMC","showType":"1","dataLength":"10","isNoEmpty":"1","defaultValue":"11","checkChongfu":"1"},{"xlsNum":"1","xlsName":"项目编号","name":"XMBH","showType":"1","isNoEmpty":"1","defaultValue":"666"},{"xlsNum":"2","xlsName":"保管期限","name":"BGQX","showType":"5","isNoEmpty":"1","defaultValue":"D30"}]}
        JSONArray titleList = data.getJSONArray("colNames");
        Set<String> checkChongfuList = new HashSet<>();
        zongshu += list.size();
        for (int j = 0; j < list.size(); j++) {  //循环匹配数据
            logger.debug(list.get(j).toString());
            int hang = num * UploadDataListener.BATCH_COUNT + (j + 2);
            Map<Integer, String> xlsData = list.get(j);
            Map<String, String> colData = new HashMap<>();
            Map<String, String> failMap = new HashMap<>();
            Boolean valVerify = false;
            String SYS_VERIFY_MSG = "";
            for (int i = 0; i < titleList.size(); i++) {  //循环表头
                JSONObject col = titleList.getJSONObject(i);
                String xlsName = col.getString("xlsName");  //表头
                Integer showType = col.getInteger("showType");  //展示类型
                Integer isNoEmpty = col.getInteger("isNoEmpty");  //是否非空
                String defaultValue = col.getString("defaultValue"); //默认值
                Integer dataLength = col.getInteger("dataLength"); //长度
                String value = xlsData.get(col.getInteger("xlsNum"));  //值
                String colName = col.getString("name");  //列名称
                Integer checkChongfu = col.getInteger("checkChongfu");  //可重复性验证
                failMap.put(colName, value);
                if (checkChongfu != null && checkChongfu == 1) {
                    //需要重复性验证的字段
                    checkChongfuList.add(colName);
                }
                if (StringUtils.isEmpty(value) && StringUtils.isNotEmpty(defaultValue)) {
                    //如果列是空的，但是默认值有值，则直接赋值默认值
                    value = defaultValue;
                }

                if (data.getInteger("type") == 1 || data.getInteger("type") == 0) {
                    colData.put("TYPE", category.getCode());
                }

                if (isNoEmpty != 0 && StringUtils.isEmpty(value)) {
                    msg.append("第" + hang + "行,列名：" + xlsName + ",不能为空;");
                    SYS_VERIFY_MSG = "第" + hang + "行,列名：" + xlsName + ",不能为空;";
                    valVerify = false;
                    continue;
                }
                if (!"iteam_code".equals(colName) && StringUtils.isNotEmpty(value) && value.length() > dataLength) {
                    msg.append("第" + hang + "行,列名：" + xlsName + ",超过最大长度" + dataLength + ";");
                    SYS_VERIFY_MSG = "第" + hang + "行,列名：" + xlsName + ",超过最大长度" + dataLength + ";";
                    valVerify = false;
                    break;
                }
                //强制内容验证 门类TYPE  全宗号QZH
                if ("TYPE".equals(colName)) {
                    if (StringUtils.isNotEmpty(value) && !category.getCode().equals(value)) {
                        msg.append("第" + hang + "行," + xlsName + "与所选门类不一致，所选门类代码是：" + category.getCode() + ";");
                        SYS_VERIFY_MSG = "第" + hang + "行," + xlsName + "与所选门类不一致，所选门类代码是：" + category.getCode() + ";";
                        valVerify = false;
                        break;
                    }
                } else if ("QZH".equals(colName)) {
                    if (StringUtils.isNotEmpty(value) && !category.getFondsCode().equals(value)) {
                        msg.append("第" + hang + "行," + xlsName + "与所选门类全宗号不一致，所选门类全宗号是：" + category.getFondsCode() + ";");
                        SYS_VERIFY_MSG = "第" + hang + "行," + xlsName + "与所选门类全宗号不一致，所选门类全宗号是：" + category.getFondsCode() + ";";
                        valVerify = false;
                        break;
                    }
                }
                //类型验证
                if (StringUtils.isNotEmpty(value) && showType == 1) {
                    String regex = "\\d+"; // 使用正则表达式 "\d+" 匹配1个或多个数字
                    Pattern pattern = Pattern.compile(regex);
                    Matcher matcher = pattern.matcher(value);
                    if (matcher.matches() == false) {
                        msg.append("第" + hang + "行,列名：" + xlsName + "类型错误,只能是数字类型;");
                        SYS_VERIFY_MSG = "第" + hang + "行,列名：" + xlsName + "类型错误,只能是数字类型;";
                        valVerify = false;
                        break;
                    }
                } else if (showType == 5) {
                    //处理下拉
                    String dictValue = null;
                    //这里查的是redis ，redis没值才会去查询数据库
                    List<TenantSysDictData> dictDataList = sysDictTypeService.selectDictDataByType(colName);
                    if (dictDataList != null) {
                        for (TenantSysDictData dict : dictDataList) {
                            if (dict.getDictLabel().equals(value) || dict.getDictValue().equals(value)) {
                                dictValue = dict.getDictValue();
                                break;
                            }
                        }
                    }

                    if (dictValue != null) {
                        value = dictValue;
                    } else if (isNoEmpty != 0) {
                        msg.append("第" + hang + "行,列名：" + xlsName + ",字典没有匹配值;");
                        SYS_VERIFY_MSG = "第" + hang + "行,列名：" + xlsName + ",字典没有匹配值;";
                        valVerify = false;
                        break;
                    }
                } else if (showType == 7) {
                    //部门
                    if (StringUtils.isNotEmpty(value)) {
                        List<SysDept> deptList = deptService.getDeptListByDeptName(value, loginUser.getSysUser().getTenantCode()).getData();
                        if (deptList != null && deptList.size() > 0) {
                            for (SysDept dept : deptList
                            ) {
                                if ("0".equals(dept.getDelFlag())) {
                                    colData.put(colName + "_ID", String.valueOf(dept.getDeptId()));
                                }
                            }

                        }
                    }

                } else if (showType == 8) {
                    //用户
                    if (StringUtils.isNotEmpty(value)) {
                        List<SysUser> userList = userService.getUserByNickName(value, loginUser.getSysUser().getTenantCode()).getData();
                        if (userList != null && userList.size() > 0) {
                            for (SysUser user : userList
                            ) {
                                if ("0".equals(user.getDelFlag())) {
                                    colData.put(colName + "_ID", String.valueOf(userList.get(0).getUserId()));
                                }
                            }
                        }
                    }
                } else if (showType == 10) {
                    //专业 中铁专用
                    if (StringUtils.isNotEmpty(value) && StringUtils.isNotEmpty(colData.get("GDCS_ID"))) {
                        //归档处室ID   GDCS_ID
                        String parentsDept = archiveMapper.getParentDept(Long.valueOf(colData.get("GDCS_ID")));
                        if (StringUtils.isNotEmpty(parentsDept)) {
                            Map<String, Object> ztMap = archiveMapper.getZT(value, parentsDept + "," + colData.get("GDCS_ID"));
                            if (ztMap != null && !ztMap.isEmpty()) {
                                colData.put(colName + "_ID", String.valueOf(ztMap.get("MAJOR_ID"))); //专业ID
                                colData.put(colName + "_CODE", String.valueOf(ztMap.get("MAJOR_CODE"))); //专业CODE
                            }
                        }
                    }
                }
                //需求入库的数据
                colData.put(colName, value);
                //如果是数值类型 并且还是空值 就移除 不保存数据库
                if (StringUtils.isEmpty(value) && showType == 1) {
                    colData.remove(colName);
                }
                valVerify = true;
            }
            if (!valVerify) {
                colData.put("SYS_VERIFY", "-1");// 未通过验证
                for (int i = 0; i < titleList.size(); i++) {
                    JSONObject coll = titleList.getJSONObject(i);
                    String valuef = xlsData.get(coll.getInteger("xlsNum"));  //值
                    String colNamef = coll.getString("name");  //列名称
                    failMap.put(colNamef, valuef);
                }
                failMap.put("SYS_VERIFY_MSG", SYS_VERIFY_MSG);
                saveData.add(colData);
                failData.add(failMap);
                errorSun++;
                //数据验证未通过  跳过这行数据   但是也存一条记录，方便后续方法知道是多少行
                continue;
            }
            //添加默认值
            setDataDefault(colData);
            colData.put("JS_TYPE", data.getString("jsType"));
            colData.put("STATE", data.getString("state"));
            colData.put("IS_DEL", "0");
            colData.put("IS_INDEX", "0");
            colData.put("CREATE_ID", String.valueOf(loginUser.getUserId()));
            colData.put("CREATE_BY", loginUser.getUsername());
            colData.put("CREATE_TIME", createTime);
            colData.put("ID", String.valueOf(SnowflakeIdGenerator.generateId()));
            saveData.add(colData);
        }
        if (category.getType() == 3 && data.getInteger("type") == 3) {
            //项目
            saveItemData(checkChongfuList);
        } else if (category.getType() == 3 && data.getInteger("type") == 1) {
            //项目中卷
            saveFolderData(null, checkChongfuList);
        } else if (category.getType() == 3 && data.getInteger("type") == 0) {
            //卷内件
            if ("-1".equals(data.getString("folderId"))) {
                //folderId = -1 时通过件和卷的档号匹配是哪个卷下的数据
                saveYqdaDataByDh(checkChongfuList);
            } else {
                saveYqdaData(data.getLong("itemId"), data.getLong("folderId"), checkChongfuList);
            }
        } else if (category.getType() == 1 && data.getInteger("type") == 1) {
            //组卷
            saveFolderData(null, checkChongfuList);
        } else if (category.getType() == 1 && data.getInteger("type") == 0) {
            //卷内件
            if ("-1".equals(data.getString("folderId"))) {
                //folderId = -1 时通过件和卷的档号匹配是哪个卷下的数据
                saveYqdaDataByDh(checkChongfuList);
            } else {
                saveYqdaData(null, data.getLong("folderId"), checkChongfuList);
            }
        } else if (category.getType() == 0) {
            saveYqdaData(null, null, checkChongfuList);
        }
        saveData.clear();
    }

    /**
     * 根据档号插入卷内件
     */
    private void saveYqdaDataByDh(Set<String> checkChongfuList) {
        int i = 0;
        SqlSession session = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);

        try {
            String codeListTable = new TenantCodeList().getTableName();
            String codeRuleTable = new TenantCodeRule().getTableName();
            String tableName = new TenantYqda().getTableName();

            TenantYqdaMapper insertMapper = session.getMapper(TenantYqdaMapper.class);
            TenantCodeListMapper codeListMapper = session.getMapper(TenantCodeListMapper.class);

            for (Map<String, String> data : saveData) {
                i++;
                String SYS_VERIFY_MSG = "";
                if (data.get("SYS_VERIFY") == null) { //没有值就是验证通过的数据
                    //重复性验证
                    if (checkChongfuList.size() > 0) {
                        Boolean bl = false;
                        for (String checkChongfu : checkChongfuList) {
                            if (StringUtils.isNotEmpty(data.get(checkChongfu))) {
                                Integer count = insertMapper.getCountByCol(checkChongfu, data.get(checkChongfu), category.getFileTableName());
                                if (count > 0) {
                                    msg.append("第" + (num * UploadDataListener.BATCH_COUNT + 1 + i) + "行数据重复已跳过，重复值为：" + data.get(checkChongfu) + ";");
                                    bl = true;
                                    errorSun++;
                                    SYS_VERIFY_MSG = "第" + (num * UploadDataListener.BATCH_COUNT + 1 + i) + "行数据重复已跳过，重复值为：" + data.get(checkChongfu) + ";";
                                    data.put("SYS_VERIFY_MSG", SYS_VERIFY_MSG);
                                    failData.add(data);
                                    break;
                                }
                            }
                        }
                        //是重复了 跳过
                        if (bl) {
                            continue;
                        }
                    }
                    //通过RQ字段判断使用的档号规则
                    String rqStr = data.get("RQ");
                    Map<String, String> rule = null;
                    if (StringUtils.isNotEmpty(rqStr)) {
                        //日期处理成8位
                        rqStr = rqStr.replace("-", "").replace("/", "").replace(".", "").replace(":", "").replace(" ", "").trim();
                        Integer rq = null;
                        if (rqStr.length() > 8) {
                            rq = Integer.valueOf(rqStr.substring(0, 8));
                        } else if (rqStr.length() < 8) {
                            rq = Integer.valueOf((rqStr + ("00000000".substring(0, 8 - rqStr.length()))));
                        } else {
                            rq = Integer.valueOf(rqStr);
                        }
                        rule = codeListMapper.getCodeListByRq(category.getId(), codeListTable, codeRuleTable, rq);
                    }
                    if (rule == null || rule.size() == 0) {
                        //使用默认档号规则
                        rule = codeListMapper.getCodeListByRq(category.getId(), codeListTable, codeRuleTable, null);
                    }
                    if (rule == null || rule.size() == 0) {
                        msg.append("第" + (num * UploadDataListener.BATCH_COUNT + 1 + i) + "行，未匹配到档号规则;");
                        SYS_VERIFY_MSG = "第" + (num * UploadDataListener.BATCH_COUNT + 1 + i) + "行，未匹配到档号规则;";
                        data.put("SYS_VERIFY_MSG", SYS_VERIFY_MSG);
                        failData.add(data);
                        errorSun++;
                        continue;
                    }
                    String jianDh = rule.get("F_COLUMNNAME"); //件档号字段
                    String juanDh = rule.get("V_COLUMNNAME"); //卷档号字段
                    String lastNode = rule.get("NODE_VALUE"); //卷和件的连接符号
                    String dhValue = data.get(jianDh);
                    if (StringUtils.isEmpty(dhValue)) {
                        msg.append("第" + (num * UploadDataListener.BATCH_COUNT + 1 + i) + "行，档号为空;");
                        SYS_VERIFY_MSG = "第" + (num * UploadDataListener.BATCH_COUNT + 1 + i) + "行，档号为空;";
                        data.put("SYS_VERIFY_MSG", SYS_VERIFY_MSG);
                        failData.add(data);
                        errorSun++;
                        continue;
                    }
                    Long jianId = insertMapper.getFolderId(jianDh, dhValue, category.getFileTableName());  //获取对应件id
                    if (jianId != null) {
                        msg.append("第" + (num * UploadDataListener.BATCH_COUNT + 1 + i) + "行，对档号：" + dhValue + "重复;");
                        SYS_VERIFY_MSG = "第" + (num * UploadDataListener.BATCH_COUNT + 1 + i) + "行，对档号：" + dhValue + "重复;";
                        data.put("SYS_VERIFY_MSG", SYS_VERIFY_MSG);
                        errorSun++;
                        failData.add(data);
                        continue;
                    }
                    dhValue = dhValue.substring(0, dhValue.lastIndexOf(lastNode));  //截取出卷的档号
                    Long folderId = insertMapper.getFolderId(juanDh, dhValue, category.getFolderTableName());  //获取对应卷id
                    if (folderId == null) {
                        msg.append("第" + (num * UploadDataListener.BATCH_COUNT + 1 + i) + "行，对应卷档号：" + dhValue + "没有找到;");
                        SYS_VERIFY_MSG = "第" + (num * UploadDataListener.BATCH_COUNT + 1 + i) + "行，对应卷档号：" + dhValue + "没有找到;";
                        data.put("SYS_VERIFY_MSG", SYS_VERIFY_MSG);
                        errorSun++;
                        failData.add(data);
                        continue;
                    }//截取出卷的档号
                    //已组卷
                    data.put("IS_ZUJUAN", "1");
                    TenantYqda yqda = new TenantYqda();
                    yqda.setColNames(data);
                    //插入分表
                    yqda.setTableName(category.getFileTableName());
                    insertMapper.insertYqdaDisperse(yqda);
                    //插入主表
                    String ID = data.get("ID");
                    data.remove("ID");
                    data.put("DA_ID", ID);
                    data.put("SUB_TABLE_NAME", category.getFileTableName());
                    yqda.setTableName(tableName);
                    yqda.setColNames(data);
                    insertMapper.insertYqda(yqda);
                    //插入关联关系
                    TenantYqdaFolder yqdaFolder = new TenantYqdaFolder();
                    yqdaFolder.setFolderId(folderId);
                    yqdaFolder.setDaId(Long.valueOf(data.get("DA_ID")));
                    insertMapper.addYqdaFolder(yqdaFolder);
                    successSun++;
                }
            }
            session.commit();
            session.clearCache();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            session.rollback();
            msg.append("从第" + (num * UploadDataListener.BATCH_COUNT + 2) + "行开始插入失败;");
            msg.append("失败原因在第" + (num * UploadDataListener.BATCH_COUNT + 1 + i) + "行，错误原因：" + e.getMessage() + ";");
            errorSun++;
        } finally {
            session.close();
        }
        logger.info("第" + (num * UploadDataListener.BATCH_COUNT + 2) + "到" + (num * UploadDataListener.BATCH_COUNT + 1 + saveData.size()) + "行，处理完成！;");
        num++;
    }


    /**
     * 件
     *
     * @param folderId
     */
    private void saveYqdaData(Long itemId, Long folderId, Set<String> checkChongfuList) {
        // 如果是mybatis,尽量别直接调用多次insert,自己写一个mapper里面新增一个方法batchInsert,所有数据一次性插入
        int i = 0;
        SqlSession session = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
        try {
            String tableName = new TenantYqda().getTableName();
            TenantYqdaMapper insertMapper = session.getMapper(TenantYqdaMapper.class);
            for (Map<String, String> data : saveData) {
                i++;
                if (data.get("SYS_VERIFY") == null) { //没有值就是验证通过的数据
                    //重复性验证
                    if (checkChongfuList.size() > 0) {
                        Boolean bl = false;
                        for (String checkChongfu : checkChongfuList) {
                            if (StringUtils.isNotEmpty(data.get(checkChongfu))) {
                                Integer count = insertMapper.getCountByCol(checkChongfu, data.get(checkChongfu), category.getFileTableName());
                                if (count > 0) {
                                    msg.append("第" + (num * UploadDataListener.BATCH_COUNT + 1 + i) + "行数据重复已跳过，重复值为：" + data.get(checkChongfu) + ";");
                                    bl = true;
                                    String SYS_VERIFY_MSG = "第" + (num * UploadDataListener.BATCH_COUNT + 1 + i) + "行数据重复已跳过，重复值为：" + data.get(checkChongfu) + ";";
                                    data.put("SYS_VERIFY_MSG", SYS_VERIFY_MSG);
                                    failData.add(data);
                                    errorSun++;
                                    break;
                                }
                            }
                        }
                        //是重复了 跳过
                        if (bl) {
                            continue;
                        }
                    }
                    //已组卷
                    if (folderId != null) {
                        data.put("IS_ZUJUAN", "1");
                    }

                    TenantYqda yqda = new TenantYqda();
                    yqda.setColNames(data);
                    //插入分表
                    yqda.setTableName(category.getFileTableName());
                    insertMapper.insertYqdaDisperse(yqda);
                    //插入主表
                    String ID = data.get("ID");
                    data.remove("ID");
                    data.put("DA_ID", ID);
                    data.put("SUB_TABLE_NAME", category.getFileTableName());
                    yqda.setTableName(tableName);
                    yqda.setColNames(data);
                    insertMapper.insertYqda(yqda);
                    //插入关联关系
                    if (itemId != null || folderId != null) {
                        TenantYqdaFolder yqdaFolder = new TenantYqdaFolder();
                        yqdaFolder.setFolderId(folderId);
                        yqdaFolder.setItemId(itemId);
                        yqdaFolder.setDaId(Long.valueOf(data.get("DA_ID")));
                        insertMapper.addYqdaFolder(yqdaFolder);
                    }
                    successSun++;
                }
            }
            session.commit();
            session.clearCache();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            session.rollback();
            msg.append("从第" + (num * UploadDataListener.BATCH_COUNT + 2) + "行开始插入失败;");
            msg.append("失败原因在第" + (num * UploadDataListener.BATCH_COUNT + 1 + i) + "行，错误原因：" + e.getMessage() + ";");
            errorSun++;
        } finally {
            session.close();
        }
        logger.info("第" + (num * UploadDataListener.BATCH_COUNT + 2) + "到" + (num * UploadDataListener.BATCH_COUNT + 1 + saveData.size()) + "行，处理完成！;");
        num++;
    }

    /**
     * 卷
     *
     * @param itemId
     */
    private void saveFolderData(Long itemId, Set<String> checkChongfuList) {
        // 如果是mybatis,尽量别直接调用多次insert,自己写一个mapper里面新增一个方法batchInsert,所有数据一次性插入
        int i = 0;
        SqlSession session = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
        try {
            String tableName = new TenantYqFolder().getTableName();
            TenantYqFolderMapper insertMapper = session.getMapper(TenantYqFolderMapper.class);
            for (Map<String, String> data : saveData) {
                i++;
                if (data.get("SYS_VERIFY") == null) { //没有值就是验证通过的数据
                    if (data.containsKey("iteam_code")) {
                        String itemCode = data.get("iteam_code");
                        data.remove("iteam_code");
                        if (StringUtils.isBlank(itemCode)) {
                            msg.append("第" + (num * UploadDataListener.BATCH_COUNT + 1 + i) + "行，项目编号为空;");
                            data.put("SYS_VERIFY_MSG", "第" + (num * UploadDataListener.BATCH_COUNT + 1 + i) + "行，项目编号为空;");
                            failData.add(data);
                            errorSun++;
                            continue;
                        }
                        String item_id = insertMapper.getYqFolderAllXMBH("ITEM_ID", itemCode, new TenantYqItem().getTableName());
                        if (StringUtils.isNotBlank(item_id)) {
                            itemId = Long.valueOf(item_id);
                        } else {
                            msg.append("第" + (num * UploadDataListener.BATCH_COUNT + 1 + i) + "行，根据项目编号未查询到项目信息;");
                            data.put("SYS_VERIFY_MSG", "第" + (num * UploadDataListener.BATCH_COUNT + 1 + i) + "行，根据项目编号未查询到项目信息;");
                            failData.add(data);
                            errorSun++;
                            continue;
                        }
                    }
                    //重复性验证
                    if (checkChongfuList.size() > 0) {
                        Boolean bl = false;
                        for (String checkChongfu : checkChongfuList) {
                            if (StringUtils.isNotEmpty(data.get(checkChongfu))) {
                                Integer count = insertMapper.getCountByCol(checkChongfu, data.get(checkChongfu), category.getFolderTableName());
                                if (count > 0) {
                                    msg.append("第" + (num * UploadDataListener.BATCH_COUNT + 1 + i) + "行数据重复已跳过，重复值为：" + data.get(checkChongfu) + ";");
                                    bl = true;
                                    String SYS_VERIFY_MSG = "第" + (num * UploadDataListener.BATCH_COUNT + 1 + i) + "行数据重复已跳过，重复值为：" + data.get(checkChongfu) + ";";
                                    data.put("SYS_VERIFY_MSG", SYS_VERIFY_MSG);
                                    failData.add(data);
                                    errorSun++;
                                    break;
                                }
                            }
                        }
                        //是重复了 跳过
                        if (bl) {
                            continue;
                        }
                    }
                    //已组项目
                    if (itemId != null) {
                        data.put("IS_PROJECT", "1");
                    }
                    TenantYqFolder folder = new TenantYqFolder();
                    folder.setColNames(data);
                    //插入分表
                    folder.setTableName(category.getFolderTableName());
                    insertMapper.insertYqFolderDisperse(folder);
                    //插入主表
                    String ID = data.get("ID");
                    data.remove("ID");
                    data.put("FOLDER_ID", ID);
                    data.put("SUB_TABLE_NAME", category.getFolderTableName());
                    folder.setTableName(tableName);
                    folder.setColNames(data);
                    insertMapper.insertYqFolder(folder);
                    //插入关联关系
                    if (itemId != null) {
                        TenantItemFolder itemFolder = new TenantItemFolder();
                        itemFolder.setFolderId(Long.valueOf(data.get("FOLDER_ID")));
                        itemFolder.setItemId(itemId);
                        insertMapper.addItemFolder(itemFolder);
                    }
                    successSun++;
                }
            }
            session.commit();
            session.clearCache();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            session.rollback();
            msg.append("从第" + (num * UploadDataListener.BATCH_COUNT + 2) + "行开始插入失败;");
            msg.append("失败原因在第" + (num * UploadDataListener.BATCH_COUNT + 1 + i) + "行，错误原因：" + e.getMessage() + ";");
            errorSun++;
        } finally {
            session.close();
        }
        logger.info("第" + (num * UploadDataListener.BATCH_COUNT + 2) + "到" + (num * UploadDataListener.BATCH_COUNT + 1 + saveData.size()) + "行，处理完成！;");
        num++;
    }

    private void saveItemData(Set<String> checkChongfuList) {
        // 如果是mybatis,尽量别直接调用多次insert,自己写一个mapper里面新增一个方法batchInsert,所有数据一次性插入
        int i = 0;
        SqlSession session = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
        try {
            String tableName = new TenantYqItem().getTableName();
            TenantYqItemMapper insertMapper = session.getMapper(TenantYqItemMapper.class);
            for (Map<String, String> data : saveData) {
                i++;
                if (data.get("SYS_VERIFY") == null) { //没有值就是验证通过的数据
                    //重复性验证
                    if (checkChongfuList.size() > 0) {
                        Boolean bl = false;
                        for (String checkChongfu : checkChongfuList) {
                            if (StringUtils.isNotEmpty(data.get(checkChongfu))) {
                                Integer count = insertMapper.getCountByCol(checkChongfu, data.get(checkChongfu), category.getItemTableName());
                                if (count > 0) {
                                    msg.append("第" + (num * UploadDataListener.BATCH_COUNT + 1 + i) + "行数据重复已跳过，重复值为：" + data.get(checkChongfu) + ";");
                                    bl = true;
                                    String SYS_VERIFY_MSG = "第" + (num * UploadDataListener.BATCH_COUNT + 1 + i) + "行数据重复已跳过，重复值为：" + data.get(checkChongfu) + ";";
                                    data.put("SYS_VERIFY_MSG", SYS_VERIFY_MSG);
                                    failData.add(data);
                                    errorSun++;
                                    break;
                                }
                            }
                        }
                        //是重复了 跳过
                        if (bl) {
                            continue;
                        }
                    }
                    TenantYqItem yqItem = new TenantYqItem();
                    yqItem.setColNames(data);
                    //插入分表
                    yqItem.setTableName(category.getItemTableName());
                    insertMapper.insertItemDisperse(yqItem);
                    //插入主表
                    String ID = data.get("ID");
                    data.remove("ID");
                    data.put("ITEM_ID", ID);
                    data.put("SUB_TABLE_NAME", category.getItemTableName());
                    yqItem.setTableName(tableName);
                    yqItem.setColNames(data);
                    insertMapper.insertItem(yqItem);
                    successSun++;
                }
            }
            session.commit();
            session.clearCache();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            session.rollback();
            msg.append("从第" + (num * UploadDataListener.BATCH_COUNT + 2) + "行开始插入失败;");
            msg.append("失败原因在第" + (num * UploadDataListener.BATCH_COUNT + 1 + i) + "行，错误原因：" + e.getMessage() + ";");
            errorSun++;
        } finally {
            session.close();
        }
        logger.info("第" + (num * UploadDataListener.BATCH_COUNT + 2) + "到" + (num * UploadDataListener.BATCH_COUNT + 1 + saveData.size()) + "行，处理完成！;");
        num++;
    }

    private void setDataDefault(Map<String, String> daData) {

        if (!daData.containsKey("GDCS")) {
            daData.put("GDCS", loginUser.getSysUser().getDept().getDeptName());
            daData.put("GDCS_ID", String.valueOf(loginUser.getSysUser().getDept().getDeptId()));
        }
        if (data.getInteger("type") == 0 || data.getInteger("type") == 1) {
            if (!daData.containsKey("GDSJ")) {
                daData.put("GDSJ", loginUser.getSysUser().getDept().getParentName());
                daData.put("GDSJ_ID", String.valueOf(loginUser.getSysUser().getDept().getParentId()));
            }
            if (!daData.containsKey("QZH")) {
                daData.put("QZH", category.getFondsCode());
            }
            if (!daData.containsKey("TYPE")) {
                daData.put("TYPE", category.getCode());
            }
        }
        if (data.getInteger("type") == 0 && (!daData.containsKey("EFILE_COUNT") || "".equals(daData.get("EFILE_COUNT")))) {
            daData.put("EFILE_COUNT", "0");
        }
        //元数据中的默认值
        for (TenantMdataList list : mdataList) {
            if (daData.get(list.getFieldName()) == null || "".equals(daData.get(list.getFieldName()))) {
                daData.put(list.getFieldName(), list.getDefaultValue());
            }
        }

    }

    public List<Map<String, String>> getHeadMap() {
        return headMap;
    }

    public void setHeadMap(List<Map<String, String>> headMap) {
        this.headMap = headMap;
    }

    public Integer getType() {
        return type;
    }

    public void setType(Integer type) {
        this.type = type;
    }

    public String getMsg() {
        return msg.toString();
    }

    public TenantCategory getCategory() {
        return category;
    }

    public void setCategory(TenantCategory category) {
        this.category = category;
    }

    public Long getTime() {
        return time;
    }

    public void setTime(Long time) {
        this.time = time;
    }

    public SqlSessionTemplate getSqlSessionTemplate() {
        return sqlSessionTemplate;
    }

    public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {
        this.sqlSessionTemplate = sqlSessionTemplate;
    }

    public LoginUser getLoginUser() {
        return loginUser;
    }

    public void setLoginUser(LoginUser loginUser) {
        this.loginUser = loginUser;
    }

    public String getCreateTime() {
        return createTime;
    }

    public void setCreateTime(String createTime) {
        this.createTime = createTime;
    }

    public ITenantSysDictTypeService getSysDictTypeService() {
        return sysDictTypeService;
    }

    public void setSysDictTypeService(ITenantSysDictTypeService sysDictTypeService) {
        this.sysDictTypeService = sysDictTypeService;
    }

    public JSONObject getData() {
        return data;
    }

    public void setData(JSONObject data) {
        this.data = data;
    }

    public List<TenantMdataList> getMdataList() {
        return mdataList;
    }

    public void setMdataList(List<TenantMdataList> mdataList) {
        this.mdataList = mdataList;
    }

    public Integer getZongshu() {
        return zongshu;
    }

    public void setZongshu(Integer zongshu) {
        this.zongshu = zongshu;
    }

    public Integer getSuccessSun() {
        return successSun;
    }

    public void setSuccessSun(Integer successSun) {
        this.successSun = successSun;
    }

    public Integer getErrorSun() {
        return errorSun;
    }

    public void setErrorSun(Integer errorSun) {
        this.errorSun = errorSun;
    }

    public List<Map<String, String>> getFailData() {
        return failData;
    }

    public void setFailData(List<Map<String, String>> failData) {
        this.failData = failData;
    }

    public ApiSystemService getUserService() {
        return userService;
    }

    public void setUserService(ApiSystemService userService) {
        this.userService = userService;
    }

    public RemoteSysDeptService getDeptService() {
        return deptService;
    }

    public void setDeptService(RemoteSysDeptService deptService) {
        this.deptService = deptService;
    }

    public ArchiveMapper getArchiveMapper() {
        return archiveMapper;
    }

    public void setArchiveMapper(ArchiveMapper archiveMapper) {
        this.archiveMapper = archiveMapper;
    }

    @Override
    public String toString() {
        return "CatalogueUploadDao{" +
                "type=" + type +
                ", msg=" + msg +
                ", category=" + category +
                ", time=" + time +
                ", loginUser=" + loginUser +
                ", createTime='" + createTime + '\'' +
                ", failData=" + failData +
                ", num=" + num +
                ", zongshu=" + zongshu +
                ", successSun=" + successSun +
                ", errorSun=" + errorSun +
                '}';
    }
}
